package com.ly.mpayment.rest.up.yujing;

import com.alibaba.fastjson.JSONObject;
import com.ly.mpayment.core.secuity.MD5;
import com.ly.mpayment.core.util.*;
import com.ly.mpayment.persist.entity.UpOrder;
import com.ly.mpayment.persist.entity.UpShopInfo;
import com.ly.mpayment.persist.service.downrechargeflow.IDownRechargeFlowService;
import com.ly.mpayment.persist.service.downshopinfo.IDownShopInfoService;
import com.ly.mpayment.persist.service.uporder.IUporderService;
import com.ly.mpayment.persist.service.upshopinfo.IUpShopInfoService;
import com.ly.mpayment.rest.recharge.RechargeRest;
import com.ly.mpayment.rest.up.util.Util;
import org.apache.log4j.Logger;
import org.mortbay.util.MultiMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestBody;

import javax.ws.rs.POST;
import javax.ws.rs.Path;

@Component
@Path("yujing")
public class YuJingRest {

    Logger logger = Logger.getLogger(YuJingRest.class);

    @Autowired
    IUporderService upOrderService;

    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;

    @Autowired
    IDownRechargeFlowService flowService;

    @Autowired
    IDownShopInfoService shopService;

    @Autowired
    IUpShopInfoService upShopInfoService;

    /**
     * channel_id	商户编号	是
     * order_no	商户订单号	是	商户订单号，下单接口商户上送的
     * stream_id	继皋流水号	否	请勿将该字段做必填项处理
     * order_time	订单完成时间	是	格式yyyyMMddHHmmss（年月日时分秒）
     * order_type	订单类型	是	01：话费充值、02：文娱充值、03：流量充值
     * account_no	充值的客户号码	否
     * face_price	充值面额	否	单位：元，流量M
     * pay_money	商品单价	否	单位：元
     * profit	交易产生的佣金金额	否	单位：元
     * status	订单状态	是	SUCCESS：成功
     * FAILED：失败
     * sign	签名	是	签名，详见1.4签名机制、2.4.3签名示例
     * voucher	运营商凭证流水号	否	有凭证的情况下才返回
     * @param data
     * @return
     */
    @SuppressWarnings("static-access")
    @Path("callBack")
    @POST
    public String callBack(@RequestBody String data) {
        logger.info("yujing_callback:" + data);
        if (!StringUtils.isBlank(data)) {
            MultiMap multiMap = Util.parceString(data);
            UpOrder order = upOrderService.findById(multiMap.getString("order_no"));
            if (order != null && multiMap.getString("status").equals("SUCCESS") && order.getStatus() == Config.status[0]) {
                order.setRemark((multiMap.containsKey("voucher") && !StringUtils.isBlank(multiMap.getString("voucher"))) ? multiMap.getString("voucher") : multiMap.getString("status"));
                RechargeRest.successUpOrder.add(order);
                return "SUCCESS";
            } else if (order != null && order.getStatus() == Config.status[0] && multiMap.getString("status").equals("FAILED")) {
                order.setRemark(multiMap.getString("status"));
                RechargeRest.failtUpOrder.add(order);

                return "SUCCESS";
            } else {
                logger.info("yujing_not_found_order:" + multiMap.getString("order_no") + "," + order.getUpphonenum());
            }
        }
        return "SUCCESS";
    }


    /**
     * 订单提交
     *
     * channel_id	商户编号	是	给商户开通的唯一编号
     * timestamp	时间戳	是	时间戳，格式yyyyMMddHHmmss（年月日时分秒）
     * 下单接口都会验证时间戳，如果与我方系统差距超过3分钟，交易会直接打回
     * order_no	商户订单号	是	商户订单号，最大32位，需要保证唯一
     * account_no	充值手机号	是	充值的手机号码
     * face_price	充值面额	是	充值面额，单位：元
     * pay_money	支付金额	否	继皋供货的价格，单位：元
     * 若上送了支付金额，并且与我方销售价不一致，交易会直接打回
     * pareacode	省份	否	若上送省份，则以上送的为准，否则根据手机号进行判断，详见3.3省份
     * spid	运营商	否	0联通、1移动、2电信 3虚商
     * 运营商不为空，则以上送的为准；
     * 运营商为空，则以我方平台判断为准（且不对携号转网的纠纷负责）；
     * productid	商品编号	否	若上送商品编号，则以上送的为准(并以此对手机号+面值校验)，否则根据手机号+面值自动匹配商品
     * notify_url	异步通知地址	否
     * sign	签名	是	签名，详见1.4签名机制
     * @param order
     * @param shop
     */
    public void commitOrder(UpOrder order, UpShopInfo shop) {

        JSONObject data = new JSONObject();
        data.put("channel_id",shop.getAppId());
        data.put("timestamp",new DateUtils().toTimeStamp());
        data.put("order_no",order.getUporderuuid());
        data.put("account_no",order.getUpphonenum());
        data.put("face_price",order.getUpShopPro().getUpfacevalue());
        //data.put("productid",order.getUpShopPro().getProductCode());
        data.put("notify_url",shop.getOrderCallAddress());
        data.put("sign",MD5.md5(StringSort.doSign(data)+shop.getUpkey()));
        String result = HttpClient.post(shop.getOrderCommitAddress(),data.toString());
        logger.info("yujing_result:"+result+","+order.getUpphonenum()+",:"+data.toString());
        try {
            //返回码为0000仅表示本次请求受理成功，不表示充值成功。充值结果通过异步通知接口返回或由商户主动发起查询交易查询。
            //返回码为1006、9999时，表示出现异常，请勿做失败，通过订单查询或客服核实后确认
            //若未接收到响应信息，请勿做失败，通过订单查询或客服核实后确认
            //参数名	参数描述	是否必填	特别说明
            //ret_code	返回码	是	详见返回码列表
            //ret_msg	返回描述	是
            //order_no	商户订单号	否	商户订单号，最大32位，需要保证唯一
            //stream_id	继皋流水号	否	请勿将该字段做必填项处理
            //响应示例
            //{
            //    "ret_code": "0000",
            //        "ret_msg": "订单已接收，充值中",
            //        "order_no ": "20181125201201100000102",
            //        "stream_id ": "test2018112520001"
            //}
            JSONObject res = JSONObject.parseObject(result);
            //提交成功
            if( res.containsKey("ret_code") && res.getString("ret_code").equals("0000")) {
                upOrderService.updateUpOrderMsg(order, res.getString("stream_id"), res.containsKey("ret_msg") ? res.getString("ret_msg") : res.getString("ret_code"));
            }else if(res.containsKey("ret_code") && !res.getString("ret_code").equals("0000")
                    && !res.getString("ret_code").equals("1006") && !res.getString("ret_code").equals("9999")) {
                order.setRemark( res.getString("ret_msg"));
                RechargeRest.failtUpOrder.add(order);
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.info(e.getMessage());
        }
    }

    /**
     * 订单查询
     * 参数名	参数描述	是否必填	特别说明
     * channel_id	商户编号	是	给商户开通的唯一编号
     * order_no	商户订单号	是	商户订单号，最大32位，需要保证唯一
     * sign	签名	是	签名，详见1.4签名机制
     * @param upOrder
     * @param shopInfo
     */
    public void queryOrder(UpOrder upOrder, UpShopInfo shopInfo) {
        JSONObject data = new JSONObject();
        data.put("order_no", upOrder.getUporderuuid());
        data.put("channel_id", shopInfo.getAppId());
        data.put("sign", MD5.md5(StringSort.doSign(data)+shopInfo.getUpkey()));
        String result =  HttpClient.post(shopInfo.getOrderStatusAddress(),data.toJSONString());
        logger.info("yujingqueryOrder:"+upOrder.getUpphonenum()+":"+result+","+data.toJSONString());
        if (!StringUtils.isBlank(result)) {

            //返回码为0000表示本次查询请求成功，具体订单状态由status决定。其他返回码仅仅表示查询请求失败，不能把订单当作失败处理，请后续再发起查询。商户充值下单后因网络或其他原因未收到我方响应报文的情况下，对于下单超过10分钟的订单如果查询返回2001错误码，表示订单不存在，建议当作失败处理。
            //建议：下单三分钟还未返回，再进行订单查询确认，查询时间间隔2分钟，订单有最终结果我方会第一时间回调。
            //参数名	参数描述	是否必填	特别说明
            //ret_code	返回码	是	详见返回码列表
            //ret_msg	返回描述	是
            //order_no	商户订单号	否
            //stream_id	继皋流水号	否
            //account_no	充值账号	否
            //status	订单状态	否	SUCCESS：充值成功
            //PROCESS：充值中
            //FAILED：充值失败
            //voucher	运营商凭证流水号	否	有凭证的情况下才返回
            //pay_money	商品单价	否	单位：元
            //        响应示例
            //充值成功时：
            //{
            //    "ret_code": "0000",
            //        "ret_msg": "充值成功",
            //        "status": "SUCCESS",
            //        "order_no ": "20181125201201100000102",
            //        "stream_id ": "test2018112520001",
            //        "account_no": "13666666666",
            //        "voucher": "",
            //        "pay_money": "99.1"
            //}
            JSONObject jsonD = JSONObject.parseObject(result);
            if(jsonD.containsKey("ret_code") && jsonD.getString("ret_code").equals("0000")){
                UpOrder order = upOrderService.findById(jsonD.getString("order_no"));
                if (order != null && jsonD.getString("status").equals("SUCCESS") && order.getStatus() == Config.status[0]) {
                    order.setRemark((jsonD.containsKey("voucher") && !StringUtils.isBlank(jsonD.getString("voucher"))) ? jsonD.getString("voucher") : jsonD.getString("ret_msg"));
                    RechargeRest.successUpOrder.add(order);
                } else if (order != null && order.getStatus() == Config.status[0] && jsonD.getString("status").equals("FAILED") ) {
                    order.setRemark(jsonD.getString("ret_msg"));
                    RechargeRest.failtUpOrder.add(order);
                } else {
                    logger.info("yujing_not_found_order:" + jsonD.getString("order_no") + "," + order.getUpphonenum());
                }
            } else if(jsonD.containsKey("ret_code") && jsonD.getString("ret_code").equals("2001")){
                upOrder.setRemark(jsonD.getString("ret_msg"));
                RechargeRest.failtUpOrder.add(upOrder);
            } else{
                logger.info("yujing_not_found_order:" + jsonD.getString("order_no") + "," + upOrder.getUpphonenum());
            }
        }
    }

}
